package com.yun.newBlog.blog.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.yun.newBlog.blog.annotation.LogPrinter;
import com.yun.newBlog.blog.common.BeanCopyUtils;
import com.yun.newBlog.blog.common.LoginUtils;
import com.yun.newBlog.blog.dao.blog.BlogMapper;
import com.yun.newBlog.blog.dao.blog.CommentMapper;
import com.yun.newBlog.blog.domain.entity.Blog;
import com.yun.newBlog.blog.domain.entity.Comment;
import com.yun.newBlog.blog.mapper.BlogMapper2;
import com.yun.newBlog.blog.service.IBlogService;
import com.yun.newBlog.blog.vo.*;
import lombok.extern.java.Log;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import tk.mybatis.mapper.entity.Example;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 博客接口实现类
 */
@Service("blogService")
@Slf4j
public class BlogServiceImpl implements IBlogService {

    @Autowired
    private CommentMapper commentMapper;

    @Autowired
    private BlogMapper blogMapper;

    @Autowired
    private BlogMapper2 blogMapper2;

    /**
     * 博客列表分页查询
     * @param queryVo
     */
    @Override
    @LogPrinter(type = "queryForPage")
    public Page<BlogPageQueryOutVO> queryForPage(BlogQueryVo queryVo) {
        PageHelper.startPage(queryVo.getCurrent(), 10);
        Page<BlogPageQueryOutVO> page = null;
        if(!StringUtils.isEmpty(queryVo.getSort())&&!StringUtils.isEmpty(queryVo.getTag())) {
            page = blogMapper.queryPageBySortAndTag(queryVo.getSort(), queryVo.getTag());
        } else {
            page = blogMapper.queryPageBySort(queryVo.getSort());
        }

        Boolean isLogin = false;

        LoginSuccessResponseVo loginSuccessResponseVo = LoginUtils.isLogin();
        if(loginSuccessResponseVo != null){
            if("admin".equals(loginSuccessResponseVo.getRole())){
                isLogin = true;
            }
        }

        List<BlogPageQueryOutVO> blogList = page.getResult();
        for(BlogPageQueryOutVO blogOut: blogList) {
            blogOut.setIsLogin(isLogin);
        }

        return page;
    }

    /**
     * 查询博客列表
     * @param queryVo
     * @return
     */
    @Override
    //@Cacheable("blogList")
    @LogPrinter(type = "queryBlogList")
    public List<BlogPageQueryOutVO> queryBlogList(BlogQueryVo queryVo) {
        String sort = queryVo.getSort();
        String tag = queryVo.getTag();

        Example example = new Example(Blog.class);
        Example.Criteria criteria = example.createCriteria();

        if(!StringUtils.isEmpty(sort)) {
            criteria.andEqualTo("sort",sort);
        }
        if(!StringUtils.isEmpty(tag)) {
            criteria.andEqualTo("tag",tag);
        }
        example.orderBy("crtTim").desc();//排序

        List<Blog> blogList = blogMapper.selectByExample(example);
        List<BlogPageQueryOutVO> blogOutList = renderBlogPageVO(blogList);

        return blogOutList;
    }

    /**
     * 获取文章所有标签列表
     * @return
     */
    @LogPrinter(type = "getTagList")
    @Override
    @Cacheable("tags")
    public List<TagVO> getTagList() {

        Set<String> tagSet = new HashSet<>();
        List<Blog> blogList = blogMapper.selectAll();
        if(!StringUtils.isEmpty(blogList)) {
            tagSet = blogList.stream()
                    .map(Blog::getTag)
                    .collect(Collectors.toSet());
        }

        List<TagVO> tagVOList = new ArrayList<>();

        for(String tag : tagSet){
            BlogQueryVo queryVo = new BlogQueryVo();
            queryVo.setSort("tech");
            queryVo.setTag(tag);
            List<BlogPageQueryOutVO> tempList = queryBlogList(queryVo);

            long count = tempList.size();
            TagVO tagVO = new TagVO();
            tagVO.setName(tag);
            tagVO.setCount(count);
            tagVOList.add(tagVO);
        }

        return tagVOList;
    }

    /**
     * 博客列表模糊搜索
     * @param queryVo
     * @return
     */
    @Override
    public List<BlogPageQueryOutVO> queryBlogListByLike(BlogQueryVo queryVo) {

        String sort = queryVo.getSort();
        String tag = queryVo.getTag();
        String like = queryVo.getLike();

        String[] properties = new String[]{"id","title","summary","tag","cover","crtTim"};

        Example example = new Example(Blog.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andLike("title","%"+like+"%");

        if(!StringUtils.isEmpty(sort)){
            criteria.andEqualTo("sort",sort);
        }

        if(!StringUtils.isEmpty(tag)){
            criteria.andEqualTo("tag",tag);
        }

        example.orderBy("crtTim").desc();//排序
        example.selectProperties(properties);
        List<Blog> blogList = blogMapper.selectByExample(example);

        if(CollectionUtils.isEmpty(blogList)){
            Example example2 = new Example(Blog.class);
            Example.Criteria criteria2 = example2.createCriteria();
            criteria2.andLike("summary","%"+like+"%");
            example2.selectProperties(properties);
            blogList = blogMapper.selectByExample(example2);
        }

        if(CollectionUtils.isEmpty(blogList)){
            Example example3 = new Example(Blog.class);
            Example.Criteria criteria3 = example3.createCriteria();
            criteria3.andLike("content","%"+like+"%");
            example3.selectProperties(properties);
            blogList = blogMapper.selectByExample(example3);
        }

        return renderBlogPageVO(blogList);
    }

    /**
     * 查询单个博客，由于查询还得更新阅读次数，所以要清除缓存
     * @param id
     * @return
     */
    @Override
    @LogPrinter(type = "queryBlogById")
    //@CacheEvict("blogList")
    public BlogVO queryBlog(Integer id) {
        // 根据ID查找文章
        Blog blog = blogMapper.selectByPrimaryKey(id);

        if(blog == null){
            return null;
        }

        // 访问量+1
        Integer eye = blog.getEye() + 1;
        blog.setEye(eye);
        blogMapper.updateByPrimaryKey(blog);

        // 查找对应的评论
        Example example = new Example(Comment.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("blogId",id);
        List<Comment> commentList = commentMapper.selectByExample(example);

        // 组织返回值
        BlogVO blogVO = new BlogVO();
        blogVO.setBlog(blog);
        blogVO.setCommentList(commentList);

        return blogVO;
    }

    /**
     * 博客保存
     * @param blog
     */
    @Override
    @CacheEvict(cacheNames = {"tags"}, allEntries = true)
    public void save(Blog blog) {
        // 设置创建时间/更新时间
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String crtTimStr = sdf.format(d);
        blog.setCrtTim(crtTimStr);

        Integer blogId = blog.getId();
        if(blogId != null){
            blogMapper.updateByPrimaryKey(blog);
        } else {
            blogMapper.insert(blog);
        }
    }

    /**
     * 保存博客评论
     * @param comment
     */
    @Override
    public void addBlogComment(Comment comment) {
        Integer blogId = comment.getBlogId();
        Blog blog = blogMapper.selectByPrimaryKey(blogId);
        Integer comments = blog.getComment();
        comments++;
        blog.setComment(comments);
        blogMapper.updateByPrimaryKey(blog);

        // 设置创建时间
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String crtTimStr = sdf.format(d);
        comment.setCrtTim(crtTimStr);

        commentMapper.insert(comment);
    }

    private List<BlogPageQueryOutVO> renderBlogPageVO(List<Blog> blogList){

        Boolean isLogin = false;

        LoginSuccessResponseVo loginSuccessResponseVo = LoginUtils.isLogin();
        if(loginSuccessResponseVo != null){
            if("admin".equals(loginSuccessResponseVo.getRole())){
                isLogin = true;
            }
        }

        List<BlogPageQueryOutVO> blogOutList = new ArrayList<>();
        if(!CollectionUtils.isEmpty(blogList)){

            for(Blog blog : blogList){
                BlogPageQueryOutVO outVO = null;
                try {
                    outVO = BeanCopyUtils.copyProperties(blog,BlogPageQueryOutVO.class);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                outVO.setIsLogin(isLogin);
                blogOutList.add(outVO);
            }
        }

        return blogOutList;

    }
}
